package org.ytor.core.sqlflow;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.core.ResolvableType;
import org.springframework.util.ClassUtils;
import org.ytor.common.util.Strs;
import org.ytor.core.sqlflow.dsl.DslCache;
import org.ytor.core.sqlflow.dsl.dsqlfile.DsqlSegment;
import org.ytor.core.sqlflow.dsl.template.TemplateParser;
import org.ytor.core.sqlflow.enums.SqlType;

import java.io.InputStream;
import java.util.List;

/**
 * created by yangtong on 2025/8/12 23:18:19
 * <br/>
 */
public final class SqlFlowInitSupport {

    private static final ObjectMapper YAML = new ObjectMapper(new YAMLFactory());

    /**
     * 初始化持久层BEAN
     */
    public static void init(Object bean) {
        if (!(bean instanceof BaseRepository<?> repo)) {
            return;
        }

        // 1) 确定“原始类”（不是 $$ 代理名）
        Class<?> userType = AopUtils.getTargetClass(bean);      // 这里是 Byte Buddy 子类
        Class<?> original = userType.getSuperclass();           // 这里就是 Abc.class（你的原类）

        // 2) 读取同包同名 yml（以原类名为准）
        String pkg = original.getPackageName();
        String fileName = original.getSimpleName() + ".yml";
        String basePath = pkg.isEmpty() ? "" : ClassUtils.convertClassNameToResourcePath(pkg) + "/";
        String path = basePath + fileName;                      // 不加 classpath:，走 CL 加载

        try (InputStream in = original.getClassLoader().getResourceAsStream(path)) {
            if (in != null) {
                byte[] bytes = in.readAllBytes();
                List<DsqlSegment> list = YAML.readValue(bytes, new TypeReference<>() {
                });
                for (DsqlSegment seg : list) {
                    if (Strs.isEmpty(seg.getSource())) {
                        seg.setSource(original.getName());
                    }
                    SqlType sqlType = SqlType.parseType(seg.getTemplate());
                    seg.setType(sqlType);

                    TemplateParser parser = new TemplateParser(seg.getTemplate());
                    seg.setRoot(parser.parseTemplate());

                    DslCache.register(original.getName() + "." + seg.getId(), seg);
                }
            }
        } catch (Exception e) {
            throw new IllegalStateException("加载 SQL 段落文件 失败: " + path, e);
        }

        // 3) 解析 BaseRepository<T> 的 T，并写回
        Class<?> entityClass = ResolvableType
                .forClass(userType)                 // 注意：这里用的是子类，能拿到正确泛型
                .as(BaseRepository.class)
                .getGeneric(0)
                .resolve();

        if (entityClass == null) {
            throw new IllegalStateException("无法解析 " + userType.getName() + " 的 BaseRepository<T> 泛型参数");
        }

        repo.initEntityClazz(entityClass);
    }

    private SqlFlowInitSupport() {
    }
}
